package com.wx.rabbitmq.exchange.direct;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import com.wx.rabbitmq.MqConnection;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import static com.wx.rabbitmq.exchange.ExchangeType.EXCHANGE_TYPE_DIRECT;

/**
 * @author wx
 * @Description: 消费者-交换机direct(直连模式)
 * @date 2018/11/23 002313:49
 */
public class ConsumerDirectExchange {
    /**
     * 交换机名称
     */
    static final String EXCHANGE_DIREC = "test_direct_exchange";
    /**
     * 绑定队列的路由key
     */
    static final String ROUTING_DIREC_KEY = "test.direct";


    public static void main(String[] agrs) throws IOException, TimeoutException, InterruptedException {
        //1.获取connection
        Connection connection = MqConnection.getConnection();

        //2.通过connection创建一个Channel
        Channel channel = connection.createChannel();

        //3. 声明一个队列的名称
        String queueName = "test_direct_queue";

        /**
         * 4.声明交换机 exchange=交换机名称、type=交换机类型、durable=是否持久化、autoDelete=如果该交换机没有绑定任何队列则自动删除、
         *   internal=是否内置,如果设置 为true,则表示是内置的交换器,客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器的方式
         *   arguments=扩展参数
         */
        channel.exchangeDeclare(EXCHANGE_DIREC, EXCHANGE_TYPE_DIRECT, true, false, false, null);

        /**
         * 5.表示声明了一个队列
         * queue=队列名称、durable=队列是否持久化、exclusive=队列是否顺序消费(相当于加了一把独占锁，此队列只能同时被一个连接访问)
         * autoDelete=如果该队列没有绑定交换机则自动删除、arguments=额外参数
         */
        channel.queueDeclare(queueName, true, false, false, null);
        //6.建立交换机和队列的绑定关系
        channel.queueBind(queueName, EXCHANGE_DIREC, ROUTING_DIREC_KEY);
        //7. 创建消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        //8. 设置Channel  queue=访问的队列名称、autoAck=是否自动签收、callback=具体消费者对象
        channel.basicConsume(queueName, true, queueingConsumer);

        while (true) {
            //9  获取消息，如果没有消息，这一步将会一直阻塞
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String msg = new String(delivery.getBody());
            System.out.println("消费端: " + msg);
        }

    }
}
